package org.apache.ibatis.type;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.util.*;

/**
 * @author xieqiaofu
 * Create time: 2019/10/10
 **/
public class TypeAliasRegistry {

    private final Map<String, Class<?>> typeAliases = new HashMap<>();

    public TypeAliasRegistry() {
        //初始化好常用结果集别名和类型映射
        registerAlias("string", String.class);

        registerAlias("byte", Byte.class);
        registerAlias("long", Long.class);
        registerAlias("short", Short.class);
        registerAlias("int", Integer.class);
        registerAlias("integer", Integer.class);
        registerAlias("float", Float.class);
        registerAlias("double", Double.class);
        registerAlias("boolean", Boolean.class);

        registerAlias("byte[]", Byte[].class);
        registerAlias("short[]", Short[].class);
        registerAlias("int[]", Integer[].class);
        registerAlias("integer[]", Integer[].class);
        registerAlias("long[]", Long[].class);
        registerAlias("double[]", Double[].class);
        registerAlias("float[]", Float[].class);
        registerAlias("boolean[]", Boolean[].class);

        registerAlias("_byte", Byte.class);
        registerAlias("_long", Long.class);
        registerAlias("_short", Short.class);
        registerAlias("_int", Integer.class);
        registerAlias("_integer", Integer.class);
        registerAlias("_float", Float.class);
        registerAlias("_double", Double.class);
        registerAlias("_boolean", Boolean.class);

        registerAlias("_byte[]", Byte[].class);
        registerAlias("_short[]", Short[].class);
        registerAlias("_int[]", Integer[].class);
        registerAlias("_integer[]", Integer[].class);
        registerAlias("_long[]", Long[].class);
        registerAlias("_double[]", Double[].class);
        registerAlias("_float[]", Float[].class);
        registerAlias("_boolean[]", Boolean[].class);

        registerAlias("date", Date.class);
        registerAlias("bigdecimal", BigDecimal.class);
        registerAlias("decimal", BigDecimal.class);
        registerAlias("biginteger", BigInteger.class);
        registerAlias("object", Object.class);

        registerAlias("date[]", Date[].class);
        registerAlias("bigdecimal[]", BigDecimal[].class);
        registerAlias("decimal[]", BigDecimal[].class);
        registerAlias("biginteger[]", BigInteger[].class);
        registerAlias("object[]", Object[].class);

        registerAlias("map", Map.class);
        registerAlias("hashmap", HashMap.class);
        registerAlias("list", List.class);
        registerAlias("arraylist", ArrayList.class);
        registerAlias("collection", Collection.class);
        registerAlias("iterator", Iterator.class);

        //java jdbc规范定义的ResultSet类型
        registerAlias("ResultSet", ResultSet.class);
    }

    public void registerAlias(String alias, Class<?> value) {
        if (null == alias) {
            throw new TypeException("The parameter alias cannot be null");
        }
        //应该是不能用中文名称key了
        String key = alias.toLowerCase(Locale.ENGLISH);
        //这里的判断是防止一个key对应多个value，会覆盖先前缓存的value，78但是多个key可以对应着同一个value
        if (typeAliases.containsKey(key) && typeAliases.get(key) != null && !typeAliases.get(key).equals(value)) {
            throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + typeAliases.get(key).getName() + "'.");
        }
        typeAliases.put(key, value);
    }
}
